home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / et / et-2_2.lha / et2.2 / src / Mark.C < prev    next >
C/C++ Source or Header  |  1990-09-19  |  5KB  |  213 lines

  1. //$Mark,MarkList$
  2. #include "Mark.h"
  3.  
  4. MetaImpl(Mark, (T(pos), T(len), T(state), 0));
  5.  
  6. Mark::Mark(int p, int l, eMarkState s, eMarkFlags flags)
  7. {
  8.     pos = p;
  9.     len = l;
  10.     state= s;
  11.     if ((flags & eMarkInclStart) == eMarkInclStart)
  12.     SetFlag(eMarkInclStart);
  13.     if ((flags & eMarkFixedSize) == eMarkFixedSize)
  14.     SetFlag(eMarkFixedSize);
  15.     if ((flags & eMarkLocked) == eMarkLocked)
  16.     SetFlag(eMarkLocked);
  17. }
  18.  
  19. Mark::Mark(Mark *m)
  20. {
  21.     pos= m->pos;
  22.     len= m->len;
  23.     state= m->state;
  24. }
  25.  
  26. int Mark::Compare(Object *op)   
  27. {
  28.     return (pos - ((Mark *)op)->pos);
  29. }
  30.  
  31. bool Mark::HasChanged (int start,int l)
  32. {
  33.     return (state != eStateNone || pos != start || len != l);
  34. }
  35.  
  36. ostream &Mark::PrintOn(ostream& s)
  37. {
  38.     Object::PrintOn(s);
  39.     return s << pos SP << len SP << state SP;
  40. }
  41.  
  42. istream &Mark::ReadFrom(istream& s)
  43. {
  44.     Object::ReadFrom(s);
  45.     return s >> pos >> len >> Enum(state);
  46. }
  47.  
  48. ostream &Mark::DisplayOn(ostream& s)
  49. {
  50.     return s << "pos =  " << pos << "\tlen = " << len << "\t" << state NL;
  51. }
  52.  
  53. Object *Mark::DeepClone()
  54. {
  55.     return new Mark(pos, len, (eMarkState)state);
  56. }
  57.  
  58. //---- class MarkList --------------------------------------------------------
  59.  
  60. MetaImpl(MarkList, (TB(doRemove)));
  61.  
  62. MarkList::MarkList(bool remove)
  63. {   
  64.     doRemove= remove;
  65. }
  66.  
  67. void MarkList::Paste(int at,int n)
  68. {
  69.     Iter next(this);
  70.     Mark *m;
  71.  
  72.     n= max(0, n);
  73.     at= max(0, at);
  74.  
  75.     while (m = (Mark*)next()) {
  76.     if (m->TestFlag(eMarkLocked))
  77.         continue;
  78.     if ((at > m->pos || (m->TestFlag(eMarkInclStart) && at == m->pos))
  79.                             && at < m->pos + m->len) {
  80.         m->state = eStateChanged;
  81.         m->len += n;
  82.         //m->ChangedWhat((void*) eMarkLength);
  83.     } else if (at < m->pos || (!m->TestFlag(eMarkInclStart) && at == m->pos)) {
  84.         m->pos += n;
  85.         //m->ChangedWhat((void*) eMarkPos);
  86.     }
  87.     }
  88. }
  89.  
  90. void MarkList::Cut(int at,int n)
  91. {
  92.     Iter next(this);
  93.     Mark *m;
  94.  
  95.     if (at < 0)
  96.     n += at;
  97.     at = max(0,at);
  98.  
  99.     // the different cases are shown as: '|' = mark positions '^' deleted range
  100.     while (m = (Mark*)next()) {
  101.  
  102.     if (m->TestFlag(eMarkLocked))
  103.         continue;
  104.  
  105.     if (m->TestFlag(eMarkFixedSize)) {
  106.         // ^ |    |   ^ includes ^ |   ^|
  107.         if (at <= m->pos && at + n >= m->pos + m->len) {
  108.         m->state = eStateDeleted;
  109.         m->len = 0;
  110.         m->pos = at;
  111.         //m->ChangedWhat((void*) eMarkDeleted);
  112.         if (doRemove) {
  113.             Remove(m);
  114.             m->FreeAll();
  115.             delete m;
  116.         }
  117.         }
  118.         // ^ ^ |    | includes ^  ^|   |
  119.         else if (at + n <= m->pos) {
  120.         m->pos -= n;
  121.         //m->ChangedWhat((void*) eMarkPos);
  122.         }
  123.  
  124.         //    |    |  ^  ^ includes |    |^  ^
  125.         else if (at >= m->pos + m->len)
  126.         ;
  127.         // ^ | ^  |,  |  ^ | ^,| ^ ^ | includes |^   ^|
  128.         else {  
  129.         Error("Cut", "should not occur");
  130.         }           
  131.  
  132.     } else {           
  133.         // | ^ ^ | includes |^   ^|
  134.         if (at >= m->pos && at + n <= m->pos + m->len) { // contained
  135.         m->state = eStateChanged;
  136.         m->len -= n;
  137.         //m->ChangedWhat((void*) eMarkLength);
  138.         }
  139.  
  140.         // ^ |    |   ^ includes ^ |   ^|
  141.         else if (at < m->pos && at + n >= m->pos + m->len) {
  142.         m->state = eStateDeleted;
  143.         m->len = 0;
  144.         m->pos = at;
  145.         //m->ChangedWhat((void*) eMarkDeleted);
  146.         if (doRemove) {
  147.             Object *tmp= Remove(m);
  148.             delete tmp;
  149.         }
  150.         }
  151.  
  152.         // ^ | ^  |
  153.         else if (at < m->pos && at + n > m->pos) {
  154.         m->len = m->pos+m->len - (at +n); 
  155.         m->pos = at;
  156.         m->state = eStateChanged;
  157.         //m->ChangedWhat((void*) eMarkPos);
  158.         }
  159.  
  160.         // |  ^ | ^
  161.         else if (at >= m->pos && at  < m->pos + m->len) {
  162.         m->len = at - m->pos;
  163.         m->state = eStateChanged;
  164.         //m->ChangedWhat((void*) eMarkLength);
  165.         }
  166.  
  167.         // ^ ^ |    | includes ^  ^|   |
  168.         else if (at + n <= m->pos) {
  169.         m->pos -= n;
  170.         //m->ChangedWhat((void*) eMarkPos);
  171.         }
  172.  
  173.         //    |    |  ^  ^ includes |    |^  ^
  174.         else if (at >= m->pos + m->len)
  175.         ;
  176.         else    
  177.         Error("Cut", "should not occur");  
  178.     }          
  179.     }
  180. }
  181.  
  182. void MarkList::RangeChanged(int at,int n)
  183. {
  184.     Iter next(this);
  185.     Mark *m;
  186.  
  187.     n = max(0,n);
  188.     at = max(0,at);
  189.  
  190.     while (m = (Mark*)next()) {
  191.     if (m->TestFlag(eMarkLocked))
  192.         continue;
  193.     if (at < m->pos && at+n >= m->pos+m->len)
  194.         m->state = eStateChanged;
  195.     else if (at >= m->pos && at < m->pos+m->len)
  196.         m->state = eStateChanged;
  197.     else if (at+n >= m->pos && at+n < m->pos+m->len)
  198.         m->state = eStateChanged;
  199.     }
  200. }
  201.  
  202. ostream& MarkList::PrintOn (ostream&s)
  203. {
  204.     OrdCollection::PrintOn(s);
  205.     return s << doRemove SP;
  206. }
  207.  
  208. istream& MarkList::ReadFrom(istream &s)
  209. {
  210.     OrdCollection::ReadFrom(s);
  211.     return s >> Bool(doRemove);
  212. }
  213.